package edu.tsinghua.ddb.main;

import java.rmi.ConnectException;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import edu.tsinghua.ddb.beans.Deletelet;
import edu.tsinghua.ddb.beans.Insertlet;
import edu.tsinghua.ddb.beans.QueryTree;
import edu.tsinghua.ddb.components.decomposer.execute.DeleteDecomposer;
import edu.tsinghua.ddb.components.decomposer.execute.InsertDecomposer;
import edu.tsinghua.ddb.data.rowset.RowSet;
import edu.tsinghua.ddb.main.gui.QueryResult;
import edu.tsinghua.ddb.site.Site;
import edu.tsinghua.ddb.site.SitePool;
import edu.tsinghua.ddb.util.TicToc;

public class ExecuteSkeleton {
	private Map<String, String> statmap;

	public ExecuteSkeleton(String cmd) throws Exception {
		if (cmd.toLowerCase().startsWith("insert")) {
			statmap = new InsertDecomposer().getInsertStatments(new Insertlet(
					cmd));
		} else if (cmd.toLowerCase().startsWith("delete")) {
			statmap = new DeleteDecomposer().getDeleteStatments(new Deletelet(
					cmd));
		} else {
			throw new SQLException("not insert nor delete!");
		}
	}

	public int executeAndGetInvolved(Set<String> involvedSites)
			throws ConnectException, Exception {
		if (statmap != null) {
			int count = 0;
			int countReturn = 0;
			for (Entry<String, String> e : statmap.entrySet()) {
				Site s = SitePool.get(e.getKey());
				involvedSites.add(e.getKey());
				count = s.execute(e.getValue());
				if (countReturn == 0)
					countReturn = count;
				else {
					countReturn += count;
				}
			}
			return countReturn;
		}
		return 0;
	}

	public QueryResult get() throws ConnectException, Exception {
		TicToc.tic();
		final Set<String> involvedSites = new HashSet<String>();
		final int k = executeAndGetInvolved(involvedSites);
		long elapse = TicToc.toc();
		final float elapsef = ((float) elapse) / 1000;
		return new QueryResult() {

			@Override
			public int commandType() {
				return 1;
			}

			@Override
			public float ellapse() {
				return elapsef;
			}

			@Override
			public int getResultCount() {
				return k;
			}

			@Override
			public RowSet getRowset() {
				return null;
			}

			@Override
			public QueryTree getTree() throws SQLException {
				return null;
			}

			@Override
			public Set<String> involvedSites() {
				return involvedSites;
			}
		};
	}
}
